'''
Created on 2011-2-5

@author: wilbur.ma
'''

import imp
import os
from configparser import ConfigParser

from pwilib.util.plugin.PluginErrors import PluginRegistrationError, \
                                            PluginUnregistrationError, \
                                            PluginActivationError, \
                                            PluginDeactivationError

class PluginManager(object):
    configFile = 'plugins.ini'
    pluginDirectory = 'plugins'
    pluginFileExt = '.py'
    
    
class DefaultPluginManager(PluginManager):
    
    def __init__(self, 
                 config_file = PluginManager.configFile, 
                 plugin_dir = PluginManager.pluginDirectory, 
                 plugin_file_ext = PluginManager.pluginFileExt):
        self.configFile = config_file
        self.pluginDirectory = plugin_dir
        self.pluginFileExt = plugin_file_ext
        self.configParser = ConfigParser()
        self.configParser.read(config_file)

        self.plugins = {}
    
    def has_plugin(self, name):
        return name in self.plugins
    
    def get_plugin(self, name):
        plugin = None
        if self.has_plugin(name):
            plugin = self.plugins[name]
        return plugin
    
    def plugins_count(self):
        return len(self.plugins)
    
    def is_plugin_active(self, name):
        active = None    # Plugin not registerd
        if self.has_plugin(name):
            active = self.get_plugin(name).activated
        return active
    
    def parse_plugin(self, name):
        pluginName = self.configParser.get('plugins', name)
        pluginFile = pluginName + self.pluginFileExt
        pluginPath = os.path.join(self.pluginDirectory, pluginFile)
        if not os.path.exists(pluginPath):
            raise PluginRegistrationError('Failed to register plugin ' + name + '. Plugin file not exists.')
        pluginModule = imp.load_source(name, pluginPath)
        plugin = getattr(pluginModule, pluginName)()
        if plugin is None:
            raise PluginRegistrationError('Failed to register plugin ' + name + '. Load Error.')
        return plugin
        
    def register(self, name):
        if self.has_plugin(name):
            raise PluginRegistrationError('Plugin ' + name + ' has been registered.')
        self.plugins[name] = self.parse_plugin(name)
    
    def unregister(self, name):
        if not self.has_plugin(name):
            raise PluginUnregistrationError('Plugin ' + name + ' not registered.' + 
                                            'Register plugin before unregistering.')
        if self.is_plugin_active(name):
            raise PluginUnregistrationError('Cannot unregister active plugin: ' + name)
        self.plugins.pop(name)
            
    def activate(self, name):
        if not self.has_plugin(name):
            raise PluginActivationError('Cannot activate unregistered plugin ' + name)
        else:
            plugin = self.get_plugin(name)
            if not plugin.activated:
                plugin.activate()
    
    def deactivate(self, name):
        if not self.has_plugin(name):
            raise PluginDeactivationError('Cannot deactivate unregistered plugin ' + name)
        else:
            plugin = self.get_plugin(name)
            if plugin.activated:
                plugin.deactivate()
    
    def tear_down(self):
        self.configFile = DefaultPluginManager.configFile
        self.pluginDirectory = DefaultPluginManager.pluginDirectory
        self.pluginFileExt = DefaultPluginManager.pluginFileExt
        self.configParser = None
        self.plugins = {}
    